﻿using Caliburn.Micro;
using SD.Infrastructure.WPF.Caliburn.Aspects;
using SD.Infrastructure.WPF.Caliburn.Base;
using SD.Infrastructure.WPF.Extensions;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel.Extensions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using SD.Infrastructure.WPF.Models;
using SlamDunk.MES.IAppService.DTOs.Outputs.ResourceContext;
using SlamDunk.MES.IAppService.Interfaces;
using SlamDunk.ValueObjects.Enums;
using SD.Infrastructure.DTOBase;
using SlamDunk.MES.IAppService.DTOs.Outputs.PlanContext;
using SlamDunk.MES.Presentation.Models;
using SD.Common;
using SlamDunk.MES.Client.ViewModels.Facility;
using SD.IOC.Core.Mediators;
using SlamDunk.MES.Presentation.Models.NotifyModels;

namespace SlamDunk.MES.Client.ViewModels.Report
{
    /// <summary>
    /// 作业计划统计ViewModel
    /// </summary>
    public class ExecutionPlanReportViewModel : ScreenBase
    {
        #region # 字段及构造器
        /// <summary>
        /// 资源定义服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IResourceContract> _resourceContract;

        /// <summary>
        /// 计划管理服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IPlanContract> _planContract;

        /// <summary>
        /// 窗口管理器
        /// </summary>
        private readonly IWindowManager _windowManager;

        /// <summary>
        /// 依赖注入构造器
        /// </summary>
        public ExecutionPlanReportViewModel(ServiceProxy<IResourceContract> resourceContract, ServiceProxy<IPlanContract> planContract, IWindowManager windowManager)
        {
            this._resourceContract = resourceContract;
            this._planContract = planContract;
            this._windowManager = windowManager;
        }
        #endregion

        #region # 属性

        #region 开始时间 —— DateTime? StartTime
        /// <summary>
        /// 开始时间
        /// </summary>
        [DependencyProperty]
        public DateTime? StartTime { get; set; }
        #endregion

        #region 结束时间 —— DateTime? EndTime
        /// <summary>
        /// 结束时间
        /// </summary>
        [DependencyProperty]
        public DateTime? EndTime { get; set; }
        #endregion

        #region 已选计划状态 —— ProductionPlanStatus? SelectedPlanStatus
        /// <summary>
        /// 已选计划状态
        /// </summary>
        [DependencyProperty]
        public ExecutionPlanStatus? SelectedPlanStatus { get; set; }
        #endregion

        #region 已选工厂模型 —— Node SelectedFacility
        /// <summary>
        /// 已选工厂模型
        /// </summary>
        [DependencyProperty]
        public Node SelectedFacility { get; set; }
        #endregion

        #region 计划状态字典 —— IDictionary<string, string> PlanStatuses
        /// <summary>
        /// 计划状态字典
        /// </summary>
        [DependencyProperty]
        public IDictionary<string, string> PlanStatuses { get; set; }
        #endregion

        #region 产品列表 —— ObservableCollection<MaterialInfo> Products
        /// <summary>
        /// 产品列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<MaterialInfo> Products { get; set; }
        #endregion

        #region 已选产品 —— MaterialInfo SelectedProduct
        /// <summary>
        /// 已选产品
        /// </summary>
        [DependencyProperty]
        public MaterialInfo SelectedProduct { get; set; }
        #endregion

        #region 作业计划列表 —— ObservableCollection<ProductionPlanReportInfo> ProductionPlanReportList
        /// <summary>
        /// 作业计划列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<ProductionPlanSummaryNm> ProductionPlanReportList { get; set; }
        #endregion
        #endregion

        #region # 方法

        //Initializations

        #region 初始化 —— override async Task OnInitializeAsync(CancellationToken cancellationToken)
        /// <summary>
        /// 初始化
        /// </summary>
        protected override async Task OnInitializeAsync(CancellationToken cancellationToken)
        {
            IEnumerable<MaterialInfo> products = await Task.Run(() => this._resourceContract.Channel.GetMaterialsByPage(null, null, null, null, null, null, 1, int.MaxValue).Datas, cancellationToken);
            this.Products = new ObservableCollection<MaterialInfo>(products);
            this.PlanStatuses = typeof(ProductionPlanStatus).GetEnumMembers();
            StartTime = DateTime.Now.AddDays(-30);
            EndTime = DateTime.Now;
            await this.ReloadProductionPlans();
        }
        #endregion

        //Actions
        #region 选择工厂模型 —— async void SelectFacility()
        /// <summary>
        /// 选择工厂模型
        /// </summary>
        public async void SelectFacility()
        {
            this.Busy();

            SelectFacilityViewModel viewModel = ResolveMediator.Resolve<SelectFacilityViewModel>();
            bool? result = await this._windowManager.ShowDialogAsync(viewModel);
            if (result == true)
            {
                this.SelectedFacility = viewModel.SelectedFacility;
            }

            this.Idle();
        }
        #endregion

        #region 清空工厂模型 —— async void ClearFacility()
        /// <summary>
        /// 清空工厂模型
        /// </summary>
        public async void ClearFacility()
        {
            this.SelectedFacility = null;
        }
        #endregion

        #region 查看作业计划 —— async void LoadProductionPlans()
        /// <summary>
        /// 查看作业计划
        /// </summary>
        public async void LoadProductionPlans()
        {
            await this.ReloadProductionPlans();
        }
        #endregion

        #region 查看明细
        /// <summary>
        /// 查看明细
        /// </summary>
        public async void LookProductionPlanReport(ProductionPlanSummaryNm productionPlanSummaryNm)
        {
            this.Busy();
            ExecutionPlanReportDetailtViewModel viewModel = ResolveMediator.Resolve<ExecutionPlanReportDetailtViewModel>();
            viewModel.Load(productionPlanSummaryNm);
            bool? result = await this._windowManager.ShowDialogAsync(viewModel);
            this.Idle();
        }
        #endregion 
        //Private

        #region 加载作业计划列表 —— async Task ReloadProductionPlans()
        /// <summary>
        /// 加载作业计划列表
        /// </summary>
        private async Task ReloadProductionPlans()
        {
            this.Busy();

            ExecutionPlanStatus? planStatus = this.SelectedPlanStatus;
            DateTime? startTime = this.StartTime;
            DateTime? endTime = this.EndTime;
            Guid? facilityId = this.SelectedFacility?.Id;
            //查询生成计划
            PageModel<ExecutionPlanInfo> pageModel = await Task.Run(() => this._planContract.Channel.GetExecutionPlansByPage(
                null,//关键字
                null, //产品Id
                null, //工艺Id
                null, //物料清单Id
                null,//生产计划Id
                planStatus,//作业计划状态
                null, //审核状态
                null, //是否已生成工单
                null, //是否已质检
                startTime,//开始时间
                endTime, //结束时间
                facilityId,//工厂模型Id
                1, //页码
                int.MaxValue));
            //作业计划集合分组
            var executionPlanGroupList = pageModel.Datas.GroupBy(x => new { x.ProductId, x.ProductInfo, x.Status, x.FacilityId, x.FacilityInfo });
            ProductionPlanReportList = new ObservableCollection<ProductionPlanSummaryNm>(
                from x in executionPlanGroupList
                select new ProductionPlanSummaryNm
                {
                    MaterialId = x.Key.ProductId,
                    MaterialName = x.Key.ProductInfo?.Name,
                    ExpGrossQuantity = x.Any() ? x.Sum(j => j.ExpGrossQuantity) : 0,
                    ExpNetQuantity = x.Any() ? x.Sum(j => j.ExpNetQuantity) : 0,
                    ExecutionPlanStatus = x.Key.Status,
                    FacilityName = x.Key.FacilityInfo?.Name,
                    FacilityId = x.Key.FacilityId
                });

            this.Idle();
        }
        #endregion

        #endregion
    }
}
